package cn.pinming.chyn.tools.entity;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

import cn.pinming.chyn.tools.exception.ChynException;
import cn.pinming.chyn.tools.exception.ChynResultCode;

public class PmDate extends Date{
	
	private static final long serialVersionUID = 7523967970034938905L;
	
	private final String DATE_FOTMAT = "yyyy-MM-dd" ;
	private final String DATETIME_FORMAT = "yyyy-MM-dd HH:mm:ss" ;
	
	private Calendar calendar = Calendar.getInstance() ;
	
	public PmDate() {
		super() ;
		calendar.setTime(this);
	}
	
	public PmDate(long millisecond) {
		super(millisecond) ;
		calendar.setTime(this);
	}
	
	public PmDate(Date date) {
		super(date.getTime()) ;
		calendar.setTime(this);
	}
	
	protected PmDate cloneThis() {
		PmDate date = new PmDate(this.getTime()) ;
		return date ; 
	}

	/**
	 * |当天开始
	 * @return
	 */
	public PmDate beginOfDay() {
		PmDate date = cloneThis() ;
		Calendar c = date.calendar ;
		c.set(Calendar.HOUR_OF_DAY, 0);
		c.set(Calendar.MINUTE, 0);
		c.set(Calendar.SECOND, 0);
		date.setTime(c.getTimeInMillis());
		return date ;
	}
	
	/**
	 * |当天结束
	 * @return
	 */
	public PmDate endOfDay() {
		PmDate date = cloneThis() ;
		Calendar c = date.calendar ;
		c.set(Calendar.HOUR_OF_DAY, 23);
		c.set(Calendar.MINUTE, 59);
		c.set(Calendar.SECOND, 59);
		date.setTime(c.getTimeInMillis());
		return date ;
	}
	
	/**
	 * |当月第一天
	 * @return
	 */
	public PmDate beginOfMonth() {
		PmDate date = cloneThis() ;
		Calendar c = date.calendar ;
		c.set(Calendar.DAY_OF_MONTH, 1);
		date.setTime(c.getTimeInMillis());
		return date.beginOfDay() ;
	}
	
	/**
	 * |当月最后一天
	 * @return
	 */
	public PmDate endOfMonth() {
		PmDate date = cloneThis() ;
		return date.offset(Calendar.MONTH, 1).beginOfMonth().yesterday().endOfDay() ;
	}
	
	/**
	 * |当前第一天
	 * @return
	 */
	public PmDate beginOfYear() {
		PmDate date = cloneThis() ;
		Calendar c = date.calendar ;
		c.set(Calendar.DAY_OF_YEAR, 1);
		date.setTime(c.getTimeInMillis());
		return date.beginOfDay() ;
	}
	
	/**
	 * |当年最后一天
	 * @return
	 */
	public PmDate endOfYear() {
		PmDate date = cloneThis() ;
		return date.offset(Calendar.YEAR, 1).beginOfYear().yesterday().endOfDay() ;
	}
	
	/**
	 * |变更时间
	 * @param field
	 * @param amount
	 * @return
	 */
	public PmDate offset(int field , int amount) {
		PmDate date = cloneThis() ;
		Calendar c = date.calendar ;
		c.add(field, amount);
		date.setTime(c.getTimeInMillis());
		return date ;
	}
	
	/**
	 * |前一天
	 * @return
	 */
	public PmDate yesterday() {
		return offset(Calendar.DAY_OF_YEAR, -1) ;
	}
	
	/**
	 * |后一天
	 * @return
	 */
	public PmDate tomorrow() {
		return offset(Calendar.DAY_OF_YEAR, 1) ;
	}
	
	@Override
	public String toString() {
		return formatDateTime() ;
	}
	
	/**
	 * |日期转换
	 * @param dateStr
	 * @return
	 * @throws ParseException
	 */
	public PmDate parseDate(String dateStr) throws ParseException {
		if(dateStr == null) {
			return null ;
		}
		// yyyy-MM-dd
		if(dateStr.length() == 10) {
			return parseDate(dateStr, DATE_FOTMAT) ;
		}
		// yyyy-MM-dd HH:mm:ss
		if(dateStr.length() == 19) {
			return parseDate(dateStr, DATETIME_FORMAT) ;
		}
		throw new ChynException(ChynResultCode.DATE_FORMAT_ERR) ;
	}
	
	/**
	 * |日期转换
	 * @param dateStr
	 * @param format
	 * @return
	 */
	public PmDate parseDate(String dateStr , String format) {
		try {
			SimpleDateFormat sdf = new SimpleDateFormat(format) ;
			return new PmDate(sdf.parse(dateStr)) ;
		} catch (ParseException e) {
			throw new ChynException(ChynResultCode.DATE_FORMAT_ERR) ;
		}
	}
	
	/**
	 * |格式化
	 * @param format
	 * @return
	 */
	public String format(String format) {
		SimpleDateFormat sdf = new SimpleDateFormat(format) ;
		return sdf.format(this) ;
	}
	
	public String formatDate() {
		return format(DATE_FOTMAT) ;
	}
	
	public String formatDateTime() {
		return format(DATETIME_FORMAT) ;
	}
	
	public int getYear() {
		return calendar.get(Calendar.YEAR) ;
	}
	
	public int getMonth() {
		return calendar.get(Calendar.MONTH) + 1 ;
	}
	
	public int getDay() {
		return calendar.get(Calendar.DAY_OF_MONTH) ;
	}
	
}
